package br.fatec.model.dao;

import java.util.HashMap;
import java.util.List;

import br.fatec.model.entity.Cliente;
import br.fatec.util.Globals;
import br.fatec.util.Persistencia;

public class ClienteDao {

	private Persistencia persis;
	private Persistencia persisThread;

	public ClienteDao() {
		Globals globals = Globals.getInstance();

		this.persis = globals.getPersistencia();
		this.persisThread = globals.getThreadPersistencia();
	}

	public void cadastrar(Cliente cliente) throws Exception {
		persis.cadastrar(cliente);
	}

	public void alterar(Cliente cliente) throws Exception {
		persis.alterar(cliente);
	}
	
	public void integrar(Cliente cliente) throws Exception {
		persisThread.alterar(cliente);
	}

	public void excluir(Cliente cliente) throws Exception {
		persisThread.excluir(cliente.getClass(), cliente.getCodigo());
	}

	public void desativar(Cliente cliente) throws Exception {
		cliente = consultar(cliente.getCodigo());

		cliente.setAtivo(false);

		persis.alterar(cliente);
	}

	public Cliente consultar(Integer codigo) throws Exception {
		String query = "select * from cliente where codigo = :codigo and ativo = :ativo";

		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("codigo", codigo);
		parametros.put("ativo", true);
		
		return (Cliente) persis.consultar(Cliente.class, query, parametros);
	}

	public Cliente consultar(String cpf) throws Exception {
		String query = "select * from cliente where cpf = :cpf and ativo = :ativo";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("cpf", cpf);
		parametros.put("ativo", true);

		return (Cliente) persis.consultar(Cliente.class, query, parametros);
	}

	@SuppressWarnings("unchecked")
	public List<Cliente> listar() throws Exception {
		String query = "select * from cliente where ativo = :ativo order by codigo asc";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("ativo", true);

		return (List<Cliente>) persis.listar(Cliente.class, query, parametros);
	}

	@SuppressWarnings("unchecked")
	public List<Cliente> listar(String nome) throws Exception {
		String query = "select * from Cliente where nome ilike :nome and ativo = :ativo order by codigo asc";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("nome", "%" + nome + "%");
		parametros.put("ativo", true);		

		return (List<Cliente>) persis.listar(Cliente.class, query, parametros);
	}
	
	@SuppressWarnings("unchecked")
	public List<Cliente> listarIntegrar() throws Exception {
		String query = "select * from cliente where integrado = :integrar order by codigo asc";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("integrar", false);	

		return (List<Cliente>) persisThread.listar(Cliente.class, query, parametros);
	}

	@SuppressWarnings("unchecked")
	public List<Cliente> filtrar(String codigo, String nome, String cpf,
			String telefone, String login, String email) throws Exception {
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		
		String query = "select * from cliente";

		query += " join (";
		query += " select * from (";
		query += " select *, row_number() over(";
		query += " partition by cliente_cod )";
		query += " as row_num";
		query += " from cliente_contato";
		query += " inner join contato on contato.codigo = cliente_contato.contato_cod";
		
		if (telefone != null && !telefone.isEmpty())
		{
			query += " where numero ilike :telefone";
			parametros.put("telefone", "%" + telefone + "%");
		}
		
		query += ") as cliente_contato_ordenados";
		query += " where cliente_contato_ordenados.row_num = 1)";
		query += " as cliente_contato_ordenados_recente";
		query += " on cliente.codigo = cliente_contato_ordenados_recente.cliente_cod";
		
		query += " inner join usuario on usuario.codigo = cliente.login";

		query += " where cliente.ativo = :ativo";

		if (codigo != null && !codigo.isEmpty())
		{
			query += " and cast(cliente.codigo as varchar(50)) ilike :codigo";
			parametros.put("codigo", "%" + codigo + "%");
		}

		if (nome != null && !nome.isEmpty())
		{
			query += " and cliente.nome ilike :nome";
			parametros.put("nome", "%" + nome + "%");
		}

		if (cpf != null && !cpf.isEmpty())
		{
			query += " and cliente.cpf ilike :cpf";
			parametros.put("cpf", "%" + cpf + "%");
		}
		
		if (email != null && !email.isEmpty())
		{
			query += " and cliente.email ilike :email";
			parametros.put("email", "%" + email + "%");
			
		}

		if (login != null && !login.isEmpty())
		{
			query += " and usuario.nome_usuario ilike :login";
			parametros.put("login", "%" + login + "%");
		}
		
		query += " order by cliente.codigo asc";

		parametros.put("ativo", true);

		return (List<Cliente>) persis.listar(Cliente.class, query, parametros);
	}
}
